package com.mgq.java8.collector;

import com.mgq.java8.stream.Dish;

import java.util.*;
import java.util.function.BinaryOperator;
import java.util.function.Function;

import static com.mgq.java8.stream.StreamTest.menu;
import static java.util.stream.Collectors.*;

/**
 * <b>功能：</b>com.mgq.java8.collector.Group<br>
 * <b>Copyright TCSL</b>
 * <li>版本&nbsp;&nbsp;&nbsp;&nbsp;修改日期&nbsp;&nbsp;&nbsp;&nbsp;部　　门&nbsp;&nbsp;&nbsp;&nbsp;作　者&nbsp;&nbsp;&nbsp;&nbsp;变更内容</li><hr>
 * <li>v1.0&nbsp;&nbsp;&nbsp;&nbsp;20220414&nbsp;&nbsp;营业后台&nbsp;&nbsp;&nbsp;&nbsp;马广奇&nbsp;&nbsp;&nbsp;&nbsp;创建类</li>
 * <br><br>
 *
 * @author 马广奇
 * @version 2022-04-14 21:35
 */
public class Group {

    public static void group() {
        //1.根据类型分组
        Map<Dish.Type, List<Dish>> collect = menu.stream().collect(groupingBy(Dish::getType));
        System.out.println(collect);
    }

    /**
     * 自定义分组
     */
    public static void customGroup() {
        Map<String, List<Dish>> collect = menu.stream().collect(groupingBy(Dish::getDishLevel));
        System.out.println(collect);
    }



    /**
     * 多级分组
     */
    public static void multiGroup() {
        Map<Dish.Type, Map<String, List<Dish>>> collect = menu.stream().collect(groupingBy(Dish::getType,
                groupingBy(Dish::getDishLevel)));
        System.out.println(collect);
    }

    /**
     * group和count一起使用
     */
    public static void groupThenCount() {
        //统计高 有多少个, 低有多少个
        Map<String, Long> collect = menu.stream().collect(groupingBy(Dish::getDishLevel, counting()));
        System.out.println(collect);
    }

    /**
     * group和Max/min/sum一起使用
     */
    public static void groupReduce() {

        Map<String, Optional<Dish>> collect = menu.stream()
                .collect(groupingBy(Dish::getDishLevel, maxBy(Comparator.comparingInt(Dish::getCalories))));

        //去掉option.此处option无用,因为group完肯定会有结果
        Map<String, Dish> collect1 = menu.stream().
                collect(groupingBy(Dish::getDishLevel,
                        collectingAndThen(maxBy(Comparator.comparingInt(Dish::getCalories)), Optional::get)));
        Map<String, Dish> collect2 = menu.stream().
                collect(toMap(Dish::getDishLevel,
                        Function.identity(), BinaryOperator.maxBy(Comparator.comparingInt(Dish::getCalories))));
       /*
          Map<String, String> phoneBook
                = people.stream().collect(
                toMap(Person::getName,
                        Person::getAddress,
                        (s, a) -> s + ", " + a));
                        */

        //分组完,求和 summingInt
        Map<String, Integer> collect3 = menu.stream().collect(groupingBy(Dish::getDishLevel, summingInt(Dish::getCalories)));
        System.out.println(collect3);

        //分组完 count
        Map<String, Long> collect4 = menu.stream().collect(groupingBy(Dish::getDishLevel, counting()));
        System.out.println(collect4);
        //分组完,对结果进行mapping
        Map<String, Set<String>> collect5 = menu.stream().collect(groupingBy(Dish::getDishLevel, mapping(dish -> {
            return dish.getName() + "-" + dish.getType();
        }, toSet())));
        System.out.println(collect5);

        System.out.println(collect);
    }

    public static void main(String[] args) {
        group();
        customGroup();
        multiGroup();
        groupThenCount();
        groupReduce();
    }
}
